package com.sunny.shop.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class JwtToken {
    private static String jwtKey;
    private static Integer expiredTimeIn;

    private static Integer defaultScoper = 8;

    @Value("${sunny.security.jwt-key}")
    private void setJwtKey(String jwtKey){
        JwtToken.jwtKey = jwtKey;
    }

    @Value("${sunny.security.token-expired-in}")
    public void setExpiredTimeIn(Integer expiredTimeIn){
        JwtToken.expiredTimeIn = expiredTimeIn;
    }

    public static String makeToken(Long uid, Integer scoper){
        return JwtToken.getToken(uid, scoper);
    }

    public static Boolean verifyToken(String token){
        try {
            Algorithm algorithm = Algorithm.HMAC256(JwtToken.jwtKey);
            JWTVerifier verify = JWT.require(algorithm).build();
            verify.verify(token);
        }catch (JWTVerificationException e){
            return false;
        }
        return true;
    }

    public static Optional<Map<String, Claim>> getClain(String token){
        DecodedJWT decodedJWT;
        Algorithm algorithm = Algorithm.HMAC256(JwtToken.jwtKey);
        JWTVerifier jwtVerifier = JWT.require(algorithm).build();
        try {
            decodedJWT = jwtVerifier.verify(token);
        }catch (JWTVerificationException e){
            return Optional.empty();
        }
        return Optional.of(decodedJWT.getClaims());
    }

    public static String makeToken(Long uid){
        return JwtToken.getToken(uid, JwtToken.defaultScoper);
    }
    private static String getToken(Long uid, Integer scoper){
        Algorithm algorithm = Algorithm.HMAC256(JwtToken.jwtKey);
        Map<String, Date> map = JwtToken.calculateExpiredIssues();
        String token = JWT.create()
                        .withClaim("uid", uid)
                        .withClaim("scope", scoper)
                        .withExpiresAt(map.get("expiredTime"))
                        .withIssuedAt(map.get("now"))
                        .sign(algorithm);
        return token;
    }

    private static Map<String, Date> calculateExpiredIssues(){
        Map<String, Date> map = new HashMap<>();
        Calendar instance = Calendar.getInstance();
        Date time = instance.getTime();
        instance.add(instance.SECOND,JwtToken.expiredTimeIn);
        map.put("now",time);
        map.put("expiredTime", instance.getTime());
        return map;
    }
}
